using System;
using System.Reflection;
using IMath;

namespace ReflectionMathDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("使用反射技术实现基于接口的编程示例");
            Console.WriteLine("====================================\n");
            
            try
            {
                // 使用反射加载实现类
                // 由于我们是直接在同一目录下创建的文件，这里假设Math.cs编译后的程序集名称为MathLib
                // 在实际应用中，应该指定完整的程序集路径
                
                // 注意：在实际运行时，需要确保MathCalculator类可以被找到
                // 这里我们直接使用当前程序集中的类型，因为所有文件都在同一个项目中
                Type calculatorType = typeof(MathLib.MathCalculator);
                
                // 创建实例
                object calculatorInstance = Activator.CreateInstance(calculatorType);
                
                // 转换为接口类型
                IMathOperation mathOperation = (IMathOperation)calculatorInstance;
                
                Console.WriteLine("反射创建实例成功，开始测试数学运算...\n");
                
                // 测试数据
                double a = 10.5;
                double b = 2.5;
                
                // 测试加法
                double sum = mathOperation.Add(a, b);
                Console.WriteLine($"{a} + {b} = {sum}");
                
                // 测试减法
                double difference = mathOperation.Subtract(a, b);
                Console.WriteLine($"{a} - {b} = {difference}");
                
                // 测试乘法
                double product = mathOperation.Multiply(a, b);
                Console.WriteLine($"{a} * {b} = {product}");
                
                // 测试除法
                try
                {
                    double quotient = mathOperation.Divide(a, b);
                    Console.WriteLine($"{a} / {b} = {quotient}");
                    
                    // 测试除零异常
                    Console.WriteLine("\n测试除零异常...");
                    quotient = mathOperation.Divide(a, 0);
                }
                catch (DivideByZeroException ex)
                {
                    Console.WriteLine($"捕获到预期异常: {ex.Message}");
                }
                
                Console.WriteLine("\n使用反射技术的方法调用测试...");
                // 演示通过反射直接调用方法
                CallMethodByReflection(calculatorInstance, "Add", a, b);
                CallMethodByReflection(calculatorInstance, "Subtract", a, b);
                CallMethodByReflection(calculatorInstance, "Multiply", a, b);
                CallMethodByReflection(calculatorInstance, "Divide", a, b);
                
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发生错误: {ex.Message}");
                Console.WriteLine(ex.StackTrace);
            }
            
            Console.WriteLine("\n按任意键退出...");
            Console.ReadKey();
        }
        
        /// <summary>
        /// 通过反射调用对象的方法
        /// </summary>
        /// <param name="instance">对象实例</param>
        /// <param name="methodName">方法名</param>
        /// <param name="parameters">方法参数</param>
        private static void CallMethodByReflection(object instance, string methodName, params object[] parameters)
        {
            try
            {
                MethodInfo methodInfo = instance.GetType().GetMethod(methodName);
                if (methodInfo != null)
                {
                    object result = methodInfo.Invoke(instance, parameters);
                    Console.WriteLine($"反射调用 {methodName} 方法结果: {result}");
                }
                else
                {
                    Console.WriteLine($"未找到方法: {methodName}");
                }
            }
            catch (TargetInvocationException ex)
            {
                Console.WriteLine($"反射调用 {methodName} 方法时发生异常: {ex.InnerException.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"反射调用 {methodName} 方法时发生错误: {ex.Message}");
            }
        }
    }
}